package service

import (
	"context"
	"errors"
	"fmt"
	"order_srv/basic/config"
	__ "order_srv/basic/orderproto"
	"order_srv/handler/dao"
	"os"
	"time"
)

// GetFinancialReconciliation 获取财务对账数据
func (s *Server) GetFinancialReconciliation(ctx context.Context, in *__.FinancialReconciliationReq) (*__.FinancialReconciliationResp, error) {
	// 参数验证
	if in.StartDate == "" && in.EndDate == "" {
		// 如果没有指定时间范围，默认查询最近30天
		endDate := time.Now().Format("2006-01-02")
		startDate := time.Now().AddDate(0, 0, -30).Format("2006-01-02")
		in.StartDate = startDate
		in.EndDate = endDate
	}

	// 设置默认分页参数
	if in.Page <= 0 {
		in.Page = 1
	}

	if in.PageSize <= 0 {
		in.PageSize = 10
	} else if in.PageSize > 100 {
		in.PageSize = 100 // 限制每页最大数量
	}

	// 构建DAO层请求，直接传递proto请求
	daoReq := in

	// 调用DAO层获取数据
	result, err := dao.GetFinancialReconciliationData(config.DB, daoReq)
	if err != nil {
		return nil, errors.New("获取财务对账数据失败: " + err.Error())
	}

	// 转换为Proto响应格式
	resp := &__.FinancialReconciliationResp{
		Total:             result.Total,
		TotalAmount:       float32(result.TotalAmount),       // 显式转换为float32类型
		TotalPlatformFee:  float32(result.TotalPlatformFee),  // 显式转换为float32类型
		TotalDriverIncome: float32(result.TotalDriverIncome), // 显式转换为float32类型
	}

	// 转换数据项
	for _, item := range result.Items {
		protoItem := &__.FinancialReconciliationItem{
			OrderId:         item.OrderId,
			UserId:          item.UserId,
			Username:        item.Username,
			DriverId:        item.DriverId,
			DriverName:      item.DriverName,
			OrderTime:       item.OrderTime,
			StartLocation:   item.StartLocation,
			EndLocation:     item.EndLocation,
			TotalDistance:   float32(item.TotalDistance),
			ActualPayment:   float32(item.ActualPayment),
			PlatformFee:     float32(item.PlatformFee),
			DriverIncome:    float32(item.DriverIncome),
			OrderStatus:     item.OrderStatus,
			PaymentMethod:   item.PaymentMethod,
			PaymentTime:     item.PaymentTime,
			CouponDiscount:  float32(item.CouponDiscount),
			SurgeMultiplier: float32(item.SurgeMultiplier),
			Remark:          item.Remark,
		}
		resp.Items = append(resp.Items, protoItem)
	}

	return resp, nil
}

// ExportFinancialReconciliation 导出财务对账数据
func (s *Server) ExportFinancialReconciliation(ctx context.Context, in *__.ExportFinancialReconciliationReq) (*__.ExportOrderResp, error) {
	// 参数验证
	if in.StartDate == "" || in.EndDate == "" {
		return nil, errors.New("请指定导出日期范围")
	}

	if in.UserId == "" {
		return nil, errors.New("请指定操作人ID")
	}

	// 设置默认值
	if in.ExportFormat == "" {
		in.ExportFormat = "excel"
	}
	if in.MaxRecords == 0 {
		in.MaxRecords = 100000 // 默认最大10万条记录
	}

	// 创建导出任务（使用优化版本）
	taskID, err := dao.CreateFinancialReconciliationExportTaskV2(config.DB, in)
	if err != nil {
		return nil, err
	}

	return &__.ExportOrderResp{
		TaskId: taskID,
	}, nil
}

// GetExportProgress 获取导出进度
func (s *Server) GetExportProgress(ctx context.Context, in *__.ExportProgressReq) (*__.ExportProgressResp, error) {
	// 参数验证
	if in.TaskId == "" {
		return nil, errors.New("任务ID不能为空")
	}
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 获取导出任务
	task, err := dao.GetExportProgress(config.DB, in.TaskId, in.UserId)
	if err != nil {
		return nil, fmt.Errorf("获取导出进度失败: %v", err)
	}

	// 计算进度百分比
	progressPercent := float32(0)
	if task.TotalCount > 0 {
		progressPercent = float32(task.Processed) / float32(task.TotalCount) * 100
	}

	// 构建响应
	resp := &__.ExportProgressResp{
		TaskId:          task.TaskId,
		Status:          uint32(task.Status),
		TotalCount:      task.TotalCount,
		Processed:       task.Processed,
		ProgressPercent: progressPercent,
		FilePath:        task.FilePath,
		ErrorMsg:        task.ErrorMsg,
		StartTime:       task.StartTime.Format("2006-01-02 15:04:05"),
		FileSize:        task.FileSize,
		DownloadUrl:     task.DownloadUrl,
	}

	// 设置结束时间
	if task.CompletedAt != nil {
		resp.EndTime = task.CompletedAt.Format("2006-01-02 15:04:05")
	}

	return resp, nil
}

// GetExportTaskFinancialStatus 获取导出任务状态
func (s *Server) GetExportTaskFinancialStatus(ctx context.Context, in *__.GetExportTaskFinancialStatusReq) (*__.GetExportTaskFinancialStatusResp, error) {
	// 参数验证
	if in.TaskId == "" {
		return nil, errors.New("任务ID不能为空")
	}
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 获取导出任务
	task, err := dao.GetExportTaskFinancialStatus(config.DB, in.TaskId, in.UserId)
	if err != nil {
		return nil, fmt.Errorf("获取导出任务状态失败: %v", err)
	}

	// 构建响应
	resp := &__.ExportTaskStatusResp{
		TaskId:        task.TaskId,
		Status:        uint32(task.Status),
		TotalCount:    task.TotalCount,
		Processed:     task.Processed,
		FilePath:      task.FilePath,
		ErrorMsg:      task.ErrorMsg,
		CreatedAt:     task.CreatedAt.Format("2006-01-02 15:04:05"),
		UpdatedAt:     task.UpdatedAt.Format("2006-01-02 15:04:05"),
		FileSize:      task.FileSize,
		IsEncrypted:   task.IsEncrypted,
		EncryptionKey: task.EncryptionKey,
	}

	// 设置完成时间
	if task.CompletedAt != nil {
		resp.CompletedAt = task.CompletedAt.Format("2006-01-02 15:04:05")
	}
	return &__.GetExportTaskFinancialStatusResp{
		TaskId:     task.TaskId,
		Status:     uint32(task.Status),
		TotalCount: task.TotalCount,
		Processed:  task.Processed,
		FilePath:   task.FilePath,
		ErrorMsg:   task.ErrorMsg,
	}, nil
}

// GetExportTaskList 获取导出任务列表
func (s *Server) GetExportTaskList(ctx context.Context, in *__.ExportTaskListReq) (*__.ExportTaskListResp, error) {
	// 参数验证
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}
	if in.Page <= 0 {
		in.Page = 1
	}
	if in.PageSize <= 0 {
		in.PageSize = 10
	}

	// 获取导出任务列表
	tasks, total, err := dao.GetExportTaskList(config.DB, in.UserId, int(in.Page), int(in.PageSize), in.Status, in.StartDate, in.EndDate)
	if err != nil {
		return nil, fmt.Errorf("获取导出任务列表失败: %v", err)
	}

	// 构建响应
	var taskInfos []*__.ExportTaskInfo
	for _, task := range tasks {
		taskInfo := &__.ExportTaskInfo{
			TaskId:      task.TaskId,
			UserId:      task.UserId,
			Status:      uint32(task.Status),
			TaskType:    getTaskTypeName(task.TaskType),
			FileName:    getFileNameFromPath(task.FilePath),
			FilePath:    task.FilePath,
			FileSize:    task.FileSize,
			TotalCount:  task.TotalCount,
			Processed:   task.Processed,
			CreatedAt:   task.CreatedAt.Format("2006-01-02 15:04:05"),
			ErrorMsg:    task.ErrorMsg,
			IsEncrypted: task.IsEncrypted,
			DownloadUrl: task.DownloadUrl,
		}

		// 设置完成时间
		if task.CompletedAt != nil {
			taskInfo.CompletedAt = task.CompletedAt.Format("2006-01-02 15:04:05")
		}

		taskInfos = append(taskInfos, taskInfo)
	}

	return &__.ExportTaskListResp{
		Tasks:    taskInfos,
		Total:    total,
		Page:     in.Page,
		PageSize: in.PageSize,
	}, nil
}

// DeleteExportTask 删除导出任务
func (s *Server) DeleteExportTask(ctx context.Context, in *__.DeleteExportTaskReq) (*__.DeleteExportTaskResp, error) {
	// 参数验证
	if in.TaskId == "" {
		return nil, errors.New("任务ID不能为空")
	}
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 删除导出任务
	err := dao.DeleteExportTask(config.DB, in.TaskId, in.UserId)
	if err != nil {
		return &__.DeleteExportTaskResp{
			Success: false,
			Message: fmt.Sprintf("删除导出任务失败: %v", err),
		}, nil
	}

	return &__.DeleteExportTaskResp{
		Success: true,
		Message: "删除成功",
	}, nil
}

// DownloadExportFile 下载导出文件
func (s *Server) DownloadExportFile(ctx context.Context, in *__.DownloadExportFileReq) (*__.DownloadExportFileResp, error) {
	// 参数验证
	if in.TaskId == "" {
		return nil, errors.New("任务ID不能为空")
	}
	if in.UserId == 0 {
		return nil, errors.New("用户ID不能为空")
	}

	// 获取导出任务
	task, err := dao.DownloadExportFile(config.DB, in.TaskId, in.UserId)
	if err != nil {
		return &__.DownloadExportFileResp{
			Success: false,
			Message: fmt.Sprintf("获取导出文件失败: %v", err),
		}, nil
	}

	// 检查任务状态
	if task.Status != 2 {
		return &__.DownloadExportFileResp{
			Success: false,
			Message: "导出任务未完成",
		}, nil
	}

	// 检查文件是否存在
	if _, err := os.Stat(task.FilePath); os.IsNotExist(err) {
		return &__.DownloadExportFileResp{
			Success: false,
			Message: "导出文件不存在",
		}, nil
	}

	return &__.DownloadExportFileResp{
		Success:     true,
		Message:     "获取下载链接成功",
		DownloadUrl: task.DownloadUrl,
		FileSize:    task.FileSize,
		FileName:    getFileNameFromPath(task.FilePath),
		IsEncrypted: task.IsEncrypted,
	}, nil
}

// getTaskTypeName 获取任务类型名称
func getTaskTypeName(taskType uint8) string {
	switch taskType {
	case 1:
		return "订单导出"
	case 2:
		return "财务对账导出"
	case 3:
		return "用户数据导出"
	default:
		return "未知类型"
	}
}

// getFileNameFromPath 从文件路径获取文件名
func getFileNameFromPath(filePath string) string {
	if filePath == "" {
		return ""
	}

	// 找到最后一个斜杠的位置
	lastSlash := -1
	for i := len(filePath) - 1; i >= 0; i-- {
		if filePath[i] == '/' || filePath[i] == '\\' {
			lastSlash = i
			break
		}
	}

	if lastSlash == -1 {
		return filePath
	}

	return filePath[lastSlash+1:]
}

// GetTransactionDetails 获取交易详情列表
func (s *Server) GetTransactionDetails(ctx context.Context, in *__.FinancialReconciliationReq) (*__.TransactionDetailResp, error) {
	// 参数验证
	if in.StartDate == "" && in.EndDate == "" {
		// 如果没有指定时间范围，默认查询最近30天
		endDate := time.Now().Format("2006-01-02")
		startDate := time.Now().AddDate(0, 0, -30).Format("2006-01-02")
		in.StartDate = startDate
		in.EndDate = endDate
	}

	// 设置默认分页参数
	if in.Page <= 0 {
		in.Page = 1
	}

	if in.PageSize <= 0 {
		in.PageSize = 10
	} else if in.PageSize > 100 {
		in.PageSize = 100 // 限制每页最大数量
	}

	// 调用DAO层获取数据
	result, err := dao.GetTransactionDetails(config.DB, in, int(in.Page), int(in.PageSize))
	if err != nil {
		return nil, errors.New("获取交易详情失败: " + err.Error())
	}

	// 转换为Proto响应格式
	resp := &__.TransactionDetailResp{
		Total: result.Total,
	}

	// 转换数据项
	for _, item := range result.Items {
		protoItem := &__.TransactionDetail{
			Id:                  item.Id,
			OrderSn:             item.OrderSn,
			TransactionType:     uint32(item.TransactionType),
			TransactionTypeName: item.TransactionTypeName,
			Amount:              float32(item.Amount),
			PlatformRevenue:     float32(item.PlatformRevenue),
			DriverRevenue:       float32(item.DriverRevenue),
			PayWay:              uint32(item.PayWay),
			PayWayName:          item.PayWayName,
			TransactionTime:     item.TransactionTime.Format("2006-01-02 15:04:05"),
			UserName:            item.UserName,
			DriverName:          item.DriverName,
			OrderStatus:         int32(item.OrderStatus),
			OrderStatusName:     item.OrderStatusName,
			Remark:              item.Remark,
		}
		resp.Items = append(resp.Items, protoItem)
	}

	return resp, nil
}

// GetTransactionDetailById 获取单条交易详情
func (s *Server) GetTransactionDetailById(ctx context.Context, req *__.TransactionDetailByIdReq) (*__.TransactionDetailResp, error) {
	// 参数验证
	if req.Id <= 0 {
		return nil, fmt.Errorf("交易详情ID不能为空")
	}

	// 调用DAO层获取数据
	detail, err := dao.GetTransactionDetailById(config.DB, req.Id)
	if err != nil {
		// 直接返回原始错误，不进行包装
		return nil, err
	}

	// 转换为Proto响应格式
	resp := &__.TransactionDetailResp{
		Total: 1,
	}

	// 转换数据项
	protoItem := &__.TransactionDetail{
		Id:                  detail.Id,
		OrderSn:             detail.OrderSn,
		TransactionType:     uint32(detail.TransactionType),
		TransactionTypeName: detail.TransactionTypeName,
		Amount:              float32(detail.Amount),
		PlatformRevenue:     float32(detail.PlatformRevenue),
		DriverRevenue:       float32(detail.DriverRevenue),
		PayWay:              uint32(detail.PayWay),
		PayWayName:          detail.PayWayName,
		TransactionTime:     detail.TransactionTime.Format("2006-01-02 15:04:05"),
		UserName:            detail.UserName,
		DriverName:          detail.DriverName,
		OrderStatus:         int32(detail.OrderStatus),
		OrderStatusName:     detail.OrderStatusName,
		Remark:              detail.Remark,
	}
	resp.Items = append(resp.Items, protoItem)

	return resp, nil
}
